package com.data.center.controller;

import com.data.center.dto.OrganizationDto;
import com.data.center.entity.Organization;
import com.data.center.exception.ResultBody;
import com.data.center.exception.exception.BizException;
import com.data.center.mapper.OrganizationMapper;
import com.data.center.service.AdminDivisionService;
import com.data.center.service.OrganizationService;
import com.data.center.util.AdminDivisionUtils;
import com.data.center.util.ExcelToListUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/Organization")
@Slf4j
@Api(tags = "组织机构")
public class OrganizationController {

    @Autowired
    AdminDivisionService adminDivisionService;

    @Autowired
    AdminDivisionUtils adminDivisionUtils;

    @Autowired
    OrganizationService organizationService;

    @Autowired
    OrganizationMapper organizationMapper;


    @PostMapping("/addOrganization")
    @ApiOperation(value = "批量添加组织")
    public ResultBody addOrganization(@RequestBody List<OrganizationDto> organizationDto) {
        Map<OrganizationDto, String> errorOrganization = new HashMap<>();
        organizationDto.forEach(item -> {
            try {
                organizationService.addOrganization(item);
            } catch (BizException e) {
                errorOrganization.put(item, e.getErrorMsg()); // 捕获无法自动处理的错误机构信息，将其返回给调用者
            }
        });
        if (errorOrganization.size() > 0) {
            log.error("调用addOrganizationList接口存在添加失败的机构信息" + errorOrganization);
            ExcelToListUtils.writeObjectsToExcel(errorOrganization, "C:\\Users\\zjjxt\\Desktop\\科协\\workspace\\data-center\\source\\OrgImportData\\导入数据质量问题.xlsx");
            return ResultBody.error(
                    "共" + errorOrganization.size() + "条组织信息入库失败, " +
                            (organizationDto.size() - errorOrganization.size()) + "条组织信息入库成功\n"
                            + errorOrganization);
        } else {
            return ResultBody.success();
        }
    }

    @PostMapping("/renameOrganization")
    @ApiOperation(value = "根据指定的更新MODE更新该ID下的组织的名称信息")
    public ResultBody renameOrganization(@RequestBody OrganizationDto organizationDto) {

        log.info("organizationDto" + organizationDto + organizationDto.getKeyWithAdditionalInformation());
        if (organizationDto.getName() == null && organizationDto.getAbbreviation() == null){
            return ResultBody.error("无可更新数据");
        }
        OrganizationDto original = organizationMapper.selectOrganizationById(organizationDto.getOrganizationId());
        if (original == null) {
            return ResultBody.error("无此组织，无法进行改名");
        }
        return ResultBody.success(organizationService.renameOrganization(original, organizationDto));
    }

    @PostMapping("/updateOrganization")
    @ApiOperation(value = "更新该ID的组织信息（不允许更新名称）")
    public ResultBody updateOrganization(@RequestBody OrganizationDto organizationDto) {
        log.info("增量信息" + organizationDto + organizationDto.getKeyWithAdditionalInformation());
        OrganizationDto original = organizationMapper.selectOrganizationById(organizationDto.getOrganizationId());
        if (original == null) {
            return ResultBody.error("ID找不到对应组织，无法更新");
        }
        return ResultBody.success(organizationService.updateOrganization(original, organizationDto));
    }

    @PostMapping("/logicalDelete")
    @ApiOperation(value = "逻辑删除该ID的组织信息")
    public ResultBody logicalDelete(@RequestParam("organizationId") String organizationId) {
        return ResultBody.success(organizationService.logicalDelete(organizationId));
    }

    @PostMapping("/physicalDelete")
    @ApiOperation(value = "物理删除该ID的组织信息（若存在对该数据的依赖则删除失败）")
    public ResultBody physicalDelete(@RequestParam("organizationId") String organizationId) {
        try {
            return ResultBody.success(organizationService.physicalDelete(organizationId));
        } catch (BizException | InvocationTargetException | IllegalAccessException e) {
            log.error("物理删除失败" + organizationId);
            return ResultBody.error(e.getMessage());
        }
    }

    @PostMapping("/merge")
    @ApiOperation(value = "合并两个组织，保留第一个ID，将第二个ID的所有依赖关系转为第一个ID")
    public ResultBody merge(@RequestParam("savedId")String savedId, @RequestParam("deletedId")String deletedId) {
        OrganizationDto saved = organizationMapper.selectOrganizationById(savedId);
        OrganizationDto deleted = organizationMapper.selectOrganizationById(deletedId);

        try {
            return ResultBody.success(organizationService.merge(saved, deleted));
        } catch (IllegalAccessException | InvocationTargetException e) {
            return ResultBody.error(e.getMessage());
        }
    }

}
